<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="./font/iconfont.js"></script>
  <title>哔哩哔哩搜索框案例</title>
  <style>
    @font-face {
      font-family: 'myfont';
      src: url('../../src/font/国潮手书.ttf');
    }

    li {
      list-style: none;
      width: 560px;
      height: 40px;
      text-align: left;
      line-height: 40px;
      font-size: 20px;
      color: purple;
      cursor: pointer;
      transition: .6s;
    }

    li:hover {
      background-color: aquamarine;
    }

    .icon {
      width: 3em;
      height: 3em;
      vertical-align: -0.15em;
      fill: currentColor;
      overflow: hidden;
    }

    body {
      background-color: #222;
    }

    svg {
      display: block;
      position: absolute;
      right: 660px;
      top: 14px;
    }

    input {
      display: block;
      width: 600px;
      height: 50px;
      margin: 0 auto;
      outline: none;
      color: yellow;
      font-size: 20px;
      font-family: myfont;
      border: 5px solid skyblue;
      background-color: #33f3;
      border-radius: 10px;
      transition: .8s;
    }

    input:hover {
      border-color: red;
    }

    #result {
      overflow: auto;
      overflow-y: hidden;
      visibility: hidden;
      width: 600px;
      height: 400px;
      height: 0px;
      margin: 0 auto;
      opacity: 0.7;
      background-color: wheat;
      border: 2px solid purple;
      border-radius: 10px;
      transition: .6s;
    }

    input:hover~#result,
    #result:hover {
      visibility: visible;
      height: 400px;
    }
  </style>
</head>

<body>

  <input type="text" id="search">
  <svg class="icon" aria-hidden="true">
    <use xlink:href="#icon-sousuo"></use>
  </svg>

  <div id="result"></div>
  <script>
    const search = document.querySelector('#search')
    const lists = document.querySelector('#result')

    let timer = null
    // 执行的函数 将数据在前端展示
    const fn = function (data) {

      timer && clearTimeout(timer)

      // 防抖
      timer = setTimeout(() => {
        // 抽离出有效数据
        const tag = data && data.result && data.result.tag

        // 清空展示区
        lists.innerHTML = ''

        // 展示新数据
        tag && tag.forEach(item => {
          const li = document.createElement('li')
          li.innerHTML = item.value
          lists.appendChild(li)
        })
      }, 300)

    }

    // 向后台请求资源
    function serchData(value) {

      // B站的搜索资源
      const url =
        `
https://s.search.bilibili.com/main/suggest?jsoncallback=fn&func=suggest&suggest_type=accurate&sub_type=tag&main_ver=v1&highlight=&userid=471806374&bangumi_acc_num=1&special_acc_num=1&topic_acc_num=1&upuser_acc_num=3&tag_num=10&special_num=10&bangumi_num=10&upuser_num=3&term=${value}&rnd=0.644667261001898&buvid=1613F481-0F57-4C91-8282-22F70267EAAA148816infoc&spmid=333.1007`

      // 在页面中创建一个标签
      const script = document.createElement('script')

      // 跨域请求资源 请求本地Server中的资源
      script.src = url

      // 将 script 标签引入
      document.body.appendChild(script)

      // 加载成功即删除
      script.onload = function () {
        this.parentNode.removeChild(this)
      }
    }

    // 搜索框输入事件监听
    search.oninput = function () {
      serchData(this.value)
    }

    // 当前列表指针
    let current = -1

    // 键控指针指向
    function select(value) {

      let lis = [...document.querySelectorAll('#result li')]
      if (lis.length === 0) return

      current += value

      // 边界控制
      if (current < 0) {
        current = -1
        return
      }

      if (current > lis.length - 1) {
        current = lis.length - 1
        return
      }

      // 控制样式
      lis[current].style.cssText = `border: 1px solid red`

      lis[current - value].style.cssText = `border: none`

    }

    // 按键注册
    window.addEventListener('keydown', e => {

      switch (e.key) {
        case 'ArrowUp': // 向上移动
          select(-1)
          break;
        case 'ArrowDown': // 向下移动
          select(1)
          break;
        default:
          break;
      }
    })
  </script>
</body>

</html>